#ifndef __CURL_TYPECHECK_GCC_H
#define __CURL_TYPECHECK_GCC_H

#include <curl/curl.h> // Include necessary header file

// Define a macro for generating warnings
#define _CURL_WARNING(id, message)                                            \
  static void __attribute__((__warning__(message)))                           \
  __attribute__((__unused__)) __attribute__((__noinline__))                   \
  id(void) { __asm__(""); }

// Macro for checking if an option takes a long argument
#define _curl_is_long_option(option) (0 < (option) && (option) < CURLOPTTYPE_OBJECTPOINT)

// Macro for checking if an option takes a char* argument
#define _curl_is_string_option(option) (\
    ((option) >= CURLOPT_ACCEPT_ENCODING && (option) <= CURLOPT_XOAUTH2_BEARER) || \
    ((option) >= CURLOPT_MAIL_AUTH && (option) <= CURLOPT_USERPWD) || \
    ((option) >= CURLOPT_UNIX_SOCKET_PATH && (option) <= CURLOPT_URL) \
)

// Macro for checking if an option takes a curl_write_callback argument
#define _curl_is_write_cb_option(option) (\
    (option) == CURLOPT_HEADERFUNCTION || \
    (option) == CURLOPT_WRITEFUNCTION \
)

// Macro for checking if an option takes a data argument to pass to a callback
#define _curl_is_cb_data_option(option) (\
    ((option) >= CURLOPT_CHUNK_DATA && (option) <= CURLOPT_SSL_CTX_DATA) || \
    (option) == CURLOPT_WRITEDATA \
)

// Define warning messages for specific options
_CURL_WARNING(_curl_easy_setopt_err_long, "curl_easy_setopt expects a long argument for this option")
_CURL_WARNING(_curl_easy_setopt_err_string, "curl_easy_setopt expects a string argument for this option")
_CURL_WARNING(_curl_easy_setopt_err_write_callback, "curl_easy_setopt expects a write callback function for this option")
_CURL_WARNING(_curl_easy_setopt_err_cb_data, "curl_easy_setopt expects a callback data argument for this option")

// Improved curl_easy_setopt macro with type-checking
#define curl_easy_setopt(handle, option, value)                               \
__extension__ ({                                                              \
  __typeof__ (option) _curl_opt = option;                                     \
  if(__builtin_constant_p(_curl_opt)) {                                       \
    if(_curl_is_long_option(_curl_opt)) {                                     \
      if(!_curl_is_long(value)) {                                             \
        _curl_easy_setopt_err_long();                                         \
      }                                                                       \
    } else if(_curl_is_string_option(_curl_opt)) {                            \
      if(!_curl_is_string(value)) {                                           \
        _curl_easy_setopt_err_string();                                       \
      }                                                                       \
    } else if(_curl_is_write_cb_option(_curl_opt)) {                          \
      if(!_curl_is_write_cb(value)) {                                         \
        _curl_easy_setopt_err_write_callback();                               \
      }                                                                       \
    } else if(_curl_is_cb_data_option(_curl_opt)) {                           \
      if(!_curl_is_cb_data(value)) {                                          \
        _curl_easy_setopt_err_cb_data();                                      \
      }                                                                       \
    }                                                                         \
  }                                                                           \
  curl_easy_setopt(handle, _curl_opt, value);                                 \
})

#endif /* __CURL_TYPECHECK_GCC_H */